package alex.thread;

import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.IntStream;

/**
 * 锁降级
 * 含义：先获取写锁, 保证写入的数据的安全; 写完数据之后, 转换为获取读锁, 这样数据就可以被多个读锁可见。
 * 而读锁lock时, 写锁不能lock。保证读的过程中, 不会修改数据。
 */
public class ReentrantReadWriteLockDemo1 {
    private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    private static ReentrantReadWriteLock.ReadLock readLock = lock.readLock();

    private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();

    private static volatile boolean update = false;

    public static void main(String[] args) {
        IntStream.range(0, 10).forEach(item -> {
            Thread thread = new Thread(() -> processData(), "T: " + item);

            thread.start();
        });
    }

    private static void processData() {
        readLock.lock();

        if (!update) {
            readLock.unlock();

            // 锁降级从写锁取到开始
            writeLock.lock();
            try {
                if (!update) {
                    // 准备数据流程
                    update = true;
                }

                readLock.lock();
            } finally {
                writeLock.unlock();
            }

            // 锁降级完成, 写锁变为读锁
        }

        try {
            // 使用数据流程
        } finally {
            readLock.unlock();
        }
    }
}
